/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.web.editors.entity;

import cn.easyplatform.entities.beans.report.JasperReportBean;
import cn.easyplatform.entities.helper.EventLogic;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.lang.stream.StringInputStream;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.utils.WebUtils;
import cn.easyplatform.studio.web.editors.*;
import cn.easyplatform.studio.web.layout.WorkbenchController;
import cn.easyplatform.studio.web.views.impl.AbstractView;
import cn.easyplatform.type.EntityType;
import cn.easyplatform.utils.SerializationUtils;
import cn.easyplatform.web.ext.cmez.CMeditor;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperReport;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.KeyEvent;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zul.*;
import org.zkoss.zul.impl.LabelImageElement;

import java.io.UnsupportedEncodingException;

/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
public class ReportEntityEditor extends AbstractEntityEditor<JasperReportBean>
        implements CodeEditor {

    private Textbox entityId; //主键

    private Textbox entityName; //名称

    private Textbox entityDesp; //描述

    private Bandbox dsId;

    private Bandbox entityTable; //数据表

    private Bandbox onRecord; //逐笔事件

    private Bandbox onGroup; //分组


    /**
     * @param workbench
     * @param entity
     * @param code
     */
    public ReportEntityEditor(WorkbenchController workbench,
                              JasperReportBean entity, char code) {
        super(workbench, entity, code);
    }

    /**
     * 初始化
     *
     * @param args
     */
    @Override
    public void create(Object... args) {
        super.create(args);
        Tabpanel tabpanel = new Tabpanel();
        Idspace is = new Idspace();
        is.setHflex("1");
        is.setVflex("1");
        is.setParent(tabpanel);

        //加载页面
        Executions.createComponents("~./include/editor/entity/report.zul", is,
                null);

        //绑定事件监听
        for (Component comp : is.getFellows()) {
            if (comp.getId().equals("report_textbox_id")) {
                entityId = (Textbox) comp;
                entityId.setValue(entity.getId());
                entityId.setReadonly(true);
            } else if (comp.getId().equals("report_textbox_name")) {
                entityName = (Textbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                entityName.setValue(entity.getName());
            } else if (comp.getId().equals("report_textbox_desp")) {
                entityDesp = (Textbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                entityDesp.setValue(entity.getDescription());
            } else if (comp.getId().equals("report_bandbox_dsId")) {
                dsId = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.addEventListener(Events.ON_OK, this);
                dsId.setValue(entity.getDsId());
            } else if (comp.getId().equals("report_bandbox_table")) {
                entityTable = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.addEventListener(Events.ON_OK, this);
                comp.getNextSibling().addEventListener(Events.ON_CLICK, this);
                entityTable.setValue(entity.getTable());
            } else if (comp.getId().equals("report_bandbox_onRecord")) {
                onRecord = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.addEventListener(Events.ON_OK, this);
                comp.getNextSibling().addEventListener(Events.ON_CLICK, this);
                if (entity.getOnRecord() != null) {
                    if (!Strings.isBlank(entity.getOnRecord().getId())) {
                        onRecord.setValue(entity.getOnRecord().getId());
                    } else if (!Strings.isBlank(entity.getOnRecord()
                            .getContent())) {
                        ((Button) onRecord.getNextSibling())
                                .setSclass("epeditor-btn-mark");
                    }
                }
            } else if (comp.getId().equals("report_bandbox_onGroup")) {
                onGroup = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.addEventListener(Events.ON_OK, this);
                comp.getNextSibling().addEventListener(Events.ON_CLICK, this);
                if (entity.getOnGroup() != null) {
                    if (!Strings.isBlank(entity.getOnGroup().getId())) {
                        onGroup.setValue(entity.getOnGroup().getId());
                    } else if (!Strings.isBlank(entity.getOnGroup()
                            .getContent())) {
                        ((Button) onGroup.getNextSibling())
                                .setSclass("epeditor-btn-mark");
                    }
                }
            } else if (comp.getId().equals("report_cmeditor_source")) {
                source = (CMeditor) comp;
                source.setTheme(Contexts.getUser().getEditorTheme());
                if (entity.getContent() != null) {
                    try {
                        source.setValue(new String(entity.getContent(), "utf8"));
                    } catch (UnsupportedEncodingException e) {
                    }
                }
                source.addEventListener(Events.ON_CHANGING, this);
            } else if (comp instanceof Button) {
                comp.addEventListener(Events.ON_CLICK, this);
                LabelImageElement xul = (LabelImageElement) comp;
                if (comp.getId().equals("report_button_query")
                        && !Strings.isBlank(entity.getQuery()))
                    xul.setSclass("epeditor-btn-mark");
                if (comp.getId().equals("report_button_orderBy")
                        && !Strings.isBlank(entity.getOrderBy()))
                    xul.setSclass("epeditor-btn-mark");
            }
        }
        workbench.addEditor(tab, tabpanel);
    }

    /**
     * 保存时,验证数据
     * @return
     */
    @Override
    protected boolean validate() {
        if (Strings.isBlank(entity.getName())) {
            WebUtils.notEmpty(Labels.getLabel("entity.name"));
            return false;
        }
        if (entity.getContent() == null || entity.getContent().length == 0) {
            WebUtils.notEmpty(Labels.getLabel("editor.report.content"));
            return false;
        }
        if (entity.getOnRecord() != null) {
            boolean notId = Strings.isBlank(entity.getOnRecord().getId());
            if (notId && Strings.isBlank(entity.getOnRecord().getContent()))
                entity.setOnRecord(null);
            else if (!notId)
                entity.getOnRecord().setContent(null);
        }
        if (entity.getOnGroup() != null) {
            boolean notId = Strings.isBlank(entity.getOnGroup().getId());
            if (notId && Strings.isBlank(entity.getOnGroup().getContent()))
                entity.setOnGroup(null);
            else if (!notId)
                entity.getOnGroup().setContent(null);
        }
        try {
            StringInputStream is = new StringInputStream(new String(
                    entity.getContent(), "utf8"));
            JasperReport jr = JasperCompileManager.compileReport(is);
            entity.setSerialize(SerializationUtils.serialize(jr));
            is.close();

        } catch (Exception ex) {
            WebUtils.showError(Labels.getLabel("editor.report.save.error",
                    new Object[]{ex.getMessage()}));
            return false;
        }
        return true;
    }

    @Override
    protected void dispatch(Event evt) {
        if (Events.ON_CHANGE.equals(evt.getName())
                || Events.ON_CHANGING.equals(evt.getName())) {
            Component c = evt.getTarget();
            if (c == entityName) {
                entity.setName(entityName.getValue());
            } else if (c == entityTable) {
                entity.setTable(entityTable.getValue());
            } else if (c == entityDesp) {
                entity.setDescription(entityDesp.getValue());
            } else if (c == dsId) {
                entity.setDsId(dsId.getValue());
            } else if (c == source) {
                try {
                    entity.setContent(source.getValue().toString()
                            .getBytes("utf8"));
                } catch (UnsupportedEncodingException e) {
                }
            }
            setDirty();
        } else if ("report_button_query".equals(evt.getTarget().getId())) {
            AbstractView.createCodeView(
                    new SimpleEditorCallback(this, (Button) evt.getTarget(),
                            "query", false), "text/x-plsql", evt.getTarget()).doOverlapped();
        } else if ("report_button_orderBy".equals(evt.getTarget().getId())) {
            AbstractView.createCodeView(
                    new SimpleEditorCallback(this, (Button) evt.getTarget(),
                            "orderBy", false), "text/x-plsql", evt.getTarget()).doOverlapped();
        } else {
            Component c = evt.getTarget();
            if (evt.getName().equals(Events.ON_OPEN) || evt instanceof KeyEvent) {// Bandbox
                if (c == dsId) {
                    AbstractView.createDatasourceView(
                            new BandboxCallback(dsId, Labels
                                    .getLabel("entity.table.db")), evt.getTarget()).doOverlapped();
                } else if (c == entityTable) {
                    if (evt instanceof OpenEvent) {
                        ((Bandbox) c).setValue(((OpenEvent) evt).getValue() + "");
                    }
                    AbstractView.createEntityView(
                            new BandboxCallback(this, (Bandbox) c), EntityType.TABLE.getName(), c)
                            .doOverlapped();
                } else {
                    if (evt instanceof OpenEvent) {
                        ((Bandbox) c).setValue(((OpenEvent) evt).getValue() + "");
                    }
                    AbstractView.createEntityView(
                            new BandboxCallback(this, (Bandbox) c),
                            EntityType.LOGIC.getName(), c).doOverlapped();
                }
            } else {
                c = c.getPreviousSibling();
                if (c == entityTable) {
                    if (!Strings.isBlank(entityTable.getValue()))
                        openEditor(evt.getTarget(), entityTable.getValue());
                } else if (c == onRecord) {
                    if (Strings.isBlank(onRecord.getValue())) {
                        if (entity.getOnRecord() == null)
                            entity.setOnRecord(new EventLogic());
                        AbstractView.createLogicView(
                                new EventLogicCallback(this, (Button) evt
                                        .getTarget(), entity.getOnRecord(), entity.getTable(),
                                        "OnRecord"), evt
                                        .getTarget()).doOverlapped();
                    } else {
                        openEditor(evt.getTarget(), onRecord.getValue());
                    }
                } else if (c == onGroup) {
                    if (Strings.isBlank(onGroup.getValue())) {
                        if (entity.getOnGroup() == null)
                            entity.setOnGroup(new EventLogic());
                        AbstractView.createLogicView(
                                new EventLogicCallback(this, (Button) evt
                                        .getTarget(), entity.getOnGroup(), entity.getTable(),
                                        "onGroup"), evt
                                        .getTarget()).doOverlapped();
                    } else {
                        openEditor(evt.getTarget(), onGroup.getValue());
                    }
                }
            }
        }
    }

    /**
     * 重绘源码
     */
    protected void refreshSource() {
    }

    @Override
    public void insertTodo() {
        source.insertText("<!-- TODO -->");
    }

    @Override
    public void insertComments() {
        source.insertText("<!-- This is a comment -->");
    }

    @Override
    public void undo() {
        source.exeCmd("undo");
    }

    @Override
    public void redo() {
        source.exeCmd("redo");
    }

    @Override
    public void selectAll() {
        source.exeCmd("selectAll");
    }

    @Override
    public void format() {
        source.exeCmd("format");
    }

    @Override
    public void formatAll() {
        source.exeCmd("formatAll");
    }

    @Override
    public void deleteLine() {
        source.exeCmd("deleteLine");
    }

    @Override
    public void indentMore() {
        source.exeCmd("indentMore");
    }

    @Override
    public void indentLess() {
        source.exeCmd("indentLess");
    }

    @Override
    public void find() {
        source.exeCmd("find");
    }

    @Override
    public void findNext() {
        source.exeCmd("findNext");
    }

    @Override
    public void findPrev() {
        source.exeCmd("findPrev");
    }

    @Override
    public void replace() {
        source.exeCmd("replace");
    }

    @Override
    public void replaceAll() {
        source.exeCmd("replaceAll");
    }
}
